// ima-adpcm.js

const stepSizeTable = [
  7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,
  34,37,41,45,50,55,60,66,73,80,88,97,107,118,130,143,
  157,173,190,209,230,253,279,307,337,371,408,449,494,544,598,658,
  724,796,876,963,1060,1166,1282,1411,1552,1707,1878,2066,2272,2499,2749,3024,
  3327,3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,10442,11487,12635,13899,
  15289,16818,18500,20350,22385,24623,27086,29794,32767
];
const indexAdjust = [-1,-1,-1,-1,2,4,6,8];

function saturate(val) {
  if (val > 32767) return 32767;
  if (val < -32768) return -32768;
  return val;
}

// 编码
export function imaAdpcmEncode(pcm16Array) {
  let state = { last: 0, stepIndex: 0 };
  let out = [];
  let buffer = 0, bufferReady = false;

  for (let i = 0; i < pcm16Array.length; i++) {
    let sample = pcm16Array[i];
    let step = stepSizeTable[state.stepIndex];
    let diff = sample - state.last;
    let sign = 0;
    let delta = 0;

    if (diff < 0) {
      sign = 8;
      diff = -diff;
    }

    let tempStep = step;
    if (diff >= tempStep) { delta |= 4; diff -= tempStep; }
    tempStep >>= 1;
    if (diff >= tempStep) { delta |= 2; diff -= tempStep; }
    tempStep >>= 1;
    if (diff >= tempStep) { delta |= 1; }

    delta |= sign;

    // 反推预测值
    let e = step >> 3;
    if (delta & 1) e += step >> 2;
    if (delta & 2) e += step >> 1;
    if (delta & 4) e += step;
    if (sign) e = -e;

    state.last = saturate(state.last + e);
    state.stepIndex += indexAdjust[delta & 7];
    if (state.stepIndex < 0) state.stepIndex = 0;
    if (state.stepIndex > 88) state.stepIndex = 88;

    // 4bit打包
    if (bufferReady) {
      out.push((buffer & 0x0F) | ((delta & 0x0F) << 4));
      bufferReady = false;
    } else {
      buffer = delta & 0x0F;
      bufferReady = true;
    }
  }
  if (bufferReady) out.push(buffer & 0x0F);

  return new Uint8Array(out);
}

// 解码
export function imaAdpcmDecode(adpcmArray, initialState = { last: 0, stepIndex: 0 }) {
  console.log('[ADPCM] 开始解码，输入数据长度:', adpcmArray.length);
  console.log('[ADPCM] 初始状态:', initialState);
  
  let state = { ...initialState };
  let out = [];

  // 验证输入数据
  if (!adpcmArray || adpcmArray.length === 0) {
    console.error('[ADPCM] 输入数据为空');
    return new Int16Array(0);
  }

  try {
    for (let i = 0; i < adpcmArray.length; i++) {
      for (let j = 0; j < 2; j++) {
        let adpcm = (j === 0) ? (adpcmArray[i] & 0x0F) : (adpcmArray[i] >> 4);
        let step = stepSizeTable[state.stepIndex];
        let e = step >> 3;
        
        if (adpcm & 1) e += step >> 2;
        if (adpcm & 2) e += step >> 1;
        if (adpcm & 4) e += step;
        if (adpcm & 8) e = -e;

        state.last = saturate(state.last + e);
        out.push(state.last);

        state.stepIndex += indexAdjust[adpcm & 7];
        if (state.stepIndex < 0) state.stepIndex = 0;
        if (state.stepIndex > 88) state.stepIndex = 88;
      }
    }
    
    console.log('[ADPCM] 解码完成，输出样本数:', out.length);
    return new Int16Array(out);
  } catch (error) {
    console.error('[ADPCM] 解码过程出错:', error);
    return new Int16Array(0);
  }
} 